package com.sakura.oj.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sakura.oj.model.dto.judge.JudgeCaseAddRequest;
import com.sakura.oj.model.dto.problem.ProblemQueryRequest;
import com.sakura.oj.model.entity.Problem;
import com.sakura.oj.model.enums.ProblemStatusEnum;
import com.sakura.oj.model.vo.HotProblemVo;
import com.sakura.oj.model.vo.ProblemVO;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 题目服务
 */
public interface ProblemService extends IService<Problem> {

    /**
     * 校验数据
     *
     * @param problem
     * @param add     对创建的数据进行校验
     */
    void validProblem(Problem problem, boolean add);

    /**
     * 获取查询条件
     *
     * @param problemQueryRequest
     * @return
     */
    QueryWrapper<Problem> getQueryWrapper(ProblemQueryRequest problemQueryRequest);

    /**
     * 获取题目封装
     *
     * @param problem
     * @return
     */
    ProblemVO getProblemVO(Problem problem);

    /**
     * 分页获取题目封装
     *
     * @param problemPage
     * @param request
     * @return
     */
    Page<ProblemVO> getProblemVOPage(Page<Problem> problemPage, HttpServletRequest request);


    /**
     * 综合条件分页查询题目
     *
     * @param page                分页参数
     * @param problemQueryRequest 查询条件
     * @return 分页题目列表
     */
    Page<Problem> searchProblemPage(Page<Problem> page, ProblemQueryRequest problemQueryRequest);

    /**
     * 更新题目标签和用例
     * 注意：如果传入的标签列表或用例列表为空，将删除该题目对应的所有标签或用例
     *
     * @param problemId     题目id
     * @param tagIdList     标签id列表，如果为null则不更新，如果为空列表则删除所有标签
     * @param judgeCaseList 用例列表，如果为null则不更新，如果为空列表则删除所有用例
     */
    void updateProblemTagsAndCases(Long problemId, List<Long> tagIdList, List<JudgeCaseAddRequest> judgeCaseList);

    /**
     * 更新题目状态
     *
     * @param id                题目id
     * @param problemStatusEnum 题目状态
     * @return 是否成功
     */
    boolean updateProblemStatus(Long id, ProblemStatusEnum problemStatusEnum);

    /**
     * 获取热门题目列表
     *
     * @param hotProblemIds 热门题目id列表
     * @return 热门题目列表
     */
    List<HotProblemVo> getHotProblems(List<Long> hotProblemIds);
}
